// Name: Base
// ID: truefantombase
// Description: Convert numbers between bases.
// By: TrueFantom <https://scratch.mit.edu/users/TrueFantom/>
// License: MIT
// Context: "Base" refers to the mathematical definition eg. base 2 is binary, base 10 is decimal, base 16 is hex.

/* generated l10n code */Scratch.translate.setup({"de":{"_Base":"Basis"},"it":{"_Base":"Basi"},"nb":{"_[A] from base [B] to base [C]":"[A] fra base [B] til base [C]","_is base [B] [A]?":"er base [B] [A]?"},"nl":{"_[A] from base [B] to base [C]":"zet [A] om van base-[B] naar base-[C]","_is base [B] [A]?":"is [A] base-[B]?"},"ru":{"_Base":"База","_[A] from base [B] to base [C]":"[A] из базы [B] в базу [C]","_is base [B] [A]?":"база [B] [A]?"},"zh-cn":{"_Base":"进制转换","_[A] from base [B] to base [C]":"把[B]进制的[A]转换成[C]","_is base [B] [A]?":"[A]是[B]进制吗？"}});/* end generated l10n code */((Scratch) => {
  "use strict";

  const icon =
    "";

  const cast = Scratch.Cast;

  const bases = [
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "10",
    "11",
    "12",
    "13",
    "14",
    "15",
    "16",
    "17",
    "18",
    "19",
    "20",
    "21",
    "22",
    "23",
    "24",
    "25",
    "26",
    "27",
    "28",
    "29",
    "30",
    "31",
    "32",
    "33",
    "34",
    "35",
    "36",
  ];
  const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  class ScratchBase {
    getInfo() {
      return {
        id: "truefantombase",
        name: Scratch.translate("Base"),

        color1: "#e200ca",

        menuIconURI: icon,

        blocks: [
          {
            opcode: "is_base_block",
            blockType: Scratch.BlockType.BOOLEAN,
            text: Scratch.translate({
              default: "is base [B] [A]?",
              description:
                "[B] will be the base like 'base 10', [A] is the text we want to check if it is in that base",
            }),
            arguments: {
              A: {
                type: Scratch.ArgumentType.STRING,
                defaultValue: "10",
              },
              B: {
                type: Scratch.ArgumentType.STRING,
                menu: "base_menu",
                defaultValue: "10",
              },
            },
          },
          {
            opcode: "base_block",
            blockType: Scratch.BlockType.REPORTER,
            text: Scratch.translate({
              default: "[A] from base [B] to base [C]",
              description:
                "[A] is the original number, [B] is the base it is currently in, [C] is the base it will be converted to.",
            }),
            arguments: {
              A: {
                type: Scratch.ArgumentType.STRING,
                defaultValue: "10",
              },
              B: {
                type: Scratch.ArgumentType.STRING,
                menu: "base_menu",
                defaultValue: "10",
              },
              C: {
                type: Scratch.ArgumentType.STRING,
                menu: "base_menu",
              },
            },
          },
        ],
        menus: {
          base_menu: {
            acceptReporters: true,
            items: bases,
          },
        },
      };
    }

    is_base_block({ A, B }) {
      if (bases.includes(cast.toString(B))) {
        return new RegExp(
          "^[" + chars.substring(0, cast.toNumber(B)) + "]+$"
        ).test(cast.toString(A));
      }
      return false;
    }
    base_block({ A, B, C }) {
      if (
        bases.includes(cast.toString(B)) &&
        bases.includes(cast.toString(C))
      ) {
        if (
          new RegExp("^[" + chars.substring(0, cast.toNumber(B)) + "]+$").test(
            cast.toString(A)
          )
        ) {
          return (
            parseInt(cast.toString(A), cast.toNumber(B))
              .toString(cast.toNumber(C))
              .toUpperCase() || "0"
          ); // Return string zero because toString() function always return strings
        }
      }
      return "0"; // Return string zero because toString() function always return strings
    }
  }

  Scratch.extensions.register(new ScratchBase());
})(Scratch);
